// TestPPR.cpp : main project file.

#include "ActionNode.h"
#include <list>
#include <iostream>
#include <windows.h>
#include "..\PPR\BuilderCSV.h"
#include "..\PPR\FilterCSV.h"
#include <fstream>
#include "hugin"
#include "..\PPR\inputPprIdid.h"

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

using boost::property_tree::ptree;
using boost::property_tree::write_xml;
using boost::property_tree::xml_writer_settings;

using namespace System;
using namespace HAPI;

void testRepresentations()
{
	//cout << "Test PPR Representations" << endl;

	//list<string> observations;
	//observations.push_back("o0");
	//observations.push_back("o1");

	//list<ActionNode> nodes;

	//ActionNode a0 = ActionNode("a0", observations);
	//ActionNode a10 = ActionNode("a0", &a0, observations);
	//ActionNode a11 = ActionNode("a1", &a0, observations);
	//a0.AddChildNode("o0", &a10);
	//a0.AddChildNode("o1", &a11);

	//list<string> endObservations;
	//ActionNode a100 = ActionNode("a1", &a10, endObservations);
	//ActionNode a101 = ActionNode("a1", &a10, endObservations);

	//a10.AddChildNode("o0", &a100);
	//a10.AddChildNode("o1", &a101);

	//nodes.push_back(a0);
	//nodes.push_back(a10);
	//nodes.push_back(a11);
	//nodes.push_back(a100);
	//nodes.push_back(a101);

	//cout << a0.ToString() << endl;
}

void testInputCSV()
{
	cout << "Test Inputting CSV Data" << endl;
	BuilderCSV builder;

	vector<string> observations;	
	observations.push_back("dont see");
	observations.push_back("see");

	vector<string> actions;
	actions.push_back("escape");
	actions.push_back("attack");

	hash_map<string, PPR> branches;

	vector<string> states;
	states.push_back("Not Under Attack");
	states.push_back("Under Attack");

	vector<string> joinStates;
	joinStates.push_back("IsUnderAttack");

	hash_map<string, PPR> trees = builder.BuildFromCSV(branches, "C:\\StarcraftReplayData\\test.csv", "IsAttacking", actions, 
														"EnemyVisible", observations, "IsUnderAttack", 3, states, joinStates);

	for(hash_map<string, PPR>::const_iterator it = trees.begin(); it != trees.end(); it++)
	{
		PPR ppr = it->second;

		cout << "--------------------" << endl;
		cout << ppr.GetRootNode()->ToString() << endl;
	}
}

void testMergeTrees()
{
	cout << "Test PPR Representations" << endl;

	list<string> observations;
	observations.push_back("o0");
	observations.push_back("o1");

	list<ActionNode> nodes;

	ActionNode a0 = ActionNode("a0", observations, "s0");
	ActionNode a10 = ActionNode("a0", &a0, observations);
	ActionNode a11 = ActionNode("a1", &a0, observations);
	a0.AddChildNode("o0", &a10);
	//a0.AddChildNode("o1", &a11);

	list<string> endObservations;
	ActionNode a100 = ActionNode("a1", &a10, endObservations);
	//ActionNode a101 = ActionNode("a1", &a10, endObservations);

	a10.AddChildNode("o0", &a100);
	//a10.AddChildNode("o1", &a101);

	PPR * tree = new PPR(&a0);


	ActionNode b0 = ActionNode("a0", observations, "s0");
	ActionNode b10 = ActionNode("a0", &b0, observations);
	b0.AddChildNode("o1", &b10);
	ActionNode b100 = ActionNode("a1", &b10, endObservations);
	b10.AddChildNode("o1", &b100);

	PPR * branch = new PPR(&b0);

	cout << a0.ToString() << endl;
	cout << "---------------------" << endl;
	cout << b0.ToString() << endl;
	cout << "---------------------" << endl;
	bool canMerge = tree->CanMergeWithBranch(*branch);
	cout << "CanMerge = " << canMerge << endl;

	if(canMerge)
	{
		tree->MergeWithBranch(*branch);
		cout << "\n---------MERGED---------" << endl;
		cout << a0.ToString() << endl;
	}

	
}

void testCSVFilter()
{
	cout << "Test StarCraft CSV Filter" << endl;

	FilterCSV filter;
	//list<list<string>> battles = filter.StarcraftFilter("UnitID", 220, "TimeSinceUnitLastLogged", 500, "C:\\StarcraftReplayData\\test2.csv");

	cout << endl;

}

hash_map<string, PPR> testFilterConvert(int treeSize, list<string> inputFiles)
{
	cout << "Test StarCraft CSV Filter Tree Size " << treeSize << endl;

	stringstream ss;
	ss << "C:\\StarcraftReplayData\\trees" << treeSize << ".txt";

	ofstream out(ss.str().c_str());
	out << "=================TREE SIZE " << treeSize << "=================" << endl;

	vector<string> observations;	
	observations.push_back("DontSee");
	observations.push_back("See");

	vector<string> actions;
	actions.push_back("Escape");
	actions.push_back("Attack");	

	vector<string> states;
	states.push_back("Not Under Attack");
	states.push_back("Under Attack");

	FilterCSV filter;
	hash_map<string, PPR> branches;
	BuilderCSV builder;

	for(list<string>::iterator its = inputFiles.begin(); its != inputFiles.end(); its++)
	{
		string file = *its;

		cout << "Processing file " << file << endl;

		cout << "Determining Unit ID's" << endl;
		hash_map<int, list<string>> unitIDs = filter.GetListOfUnitIds("UnitID", file);

		int currUnit = 1;

		//loop through all units
		for(hash_map<int, list<string>>::iterator it = unitIDs.begin(); it!=unitIDs.end(); it++)
		{
			int unitID = it->first;
			list<string> rows = it->second;

			cout << "Filtering Battles For Unit " << currUnit << " of " << unitIDs.size() << endl;
			currUnit ++;
			list<list<string>> battles = filter.StarcraftFilter("UnitID", unitID, "TimeSinceUnitLastLogged", 1500, "IsAttacking", "EnemyVisible", "IsUnderAttack", rows);

			cout << "Compressing" << endl;
			battles = filter.CompressBattlesTimeSteps(battles, 1000, "TimeSinceUnitLastLogged", "UnitID", "IsAttacking", "EnemyVisible", "IsUnderAttack");

			cout << "Building Trees" << endl;
			for(list<list<string>>::iterator it = battles.begin(); it != battles.end(); it++)
			{
				list<string> battle = *it;
				vector<string> joinStates;
				joinStates.push_back("IsUnderAttack");
				branches = builder.BuildFromCSV(branches, battle, "IsAttacking", actions, "EnemyVisible", observations, "IsUnderAttack", treeSize, states, joinStates);
			}
		}
	}

	ptree tree;
	ptree& trees = tree.add("trees", "");

	//Print branches to screen
	for(hash_map<string, PPR>::const_iterator it = branches.begin(); it != branches.end(); it++)
	{
		PPR ppr = it->second;

		//Screen Output
		cout << "-------------------------------------------" << endl;
		cout << ppr.GetRootNode()->ToStringOccurrences() << endl;

		//File Output
		out << "--------------------------------------------" << endl;
		out << ppr.GetRootNode()->ToStringOccurrences() << endl;

		ptree pprTree = ppr.GetRootNode()->ToXml();		
		trees.add_child("tree", pprTree);
	}	

	write_xml("C:\\StarcraftReplayData\\trees.xml", tree, locale(), xml_writer_settings<char>(' ', 4));
	
	out.close();

	return branches;
}

hash_map<string, PPR> testConvert(int treeSize, list<string> inputFiles)
{
	vector<string> observations;	
	observations.push_back("GL");
	observations.push_back("GR");

	vector<string> actions;
	actions.push_back("L");
	actions.push_back("OL");	
	actions.push_back("OR");	

	vector<string> states;
	states.push_back("TL");
	states.push_back("TR");

	hash_map<string, PPR> branches;
	BuilderCSV builder;

	vector<string> joinStates;
	joinStates.push_back("Model");
	joinStates.push_back("State");

	for(list<string>::iterator its = inputFiles.begin(); its != inputFiles.end(); its++)
	{
		string inputFile = *its;
		branches = builder.BuildFromCSV(branches, inputFile, "Action", actions, "Observation", observations, "State", treeSize, states, joinStates);
	}

	//Write XML results
	/*ptree tree;
	ptree& trees = tree.add("trees", "");
	for(hash_map<string, PPR>::const_iterator it = branches.begin(); it != branches.end(); it++)
	{
		PPR ppr = it->second;

		ptree pprTree = ppr.GetRootNode()->ToXml();		
		trees.add_child("tree", pprTree);
	}	
	write_xml("C:\\StarcraftReplayData\\trees.xml", tree, locale(), xml_writer_settings<char>(' ', 4));*/

	//write tikz string
	
	for(hash_map<string, PPR>::const_iterator it = branches.begin(); it != branches.end(); it++)
	{		
		ofstream myfile;
		stringstream ss;
		PPR ppr = it->second;
		string tikz = ppr.GetRootNode()->ToTikzString("","", 0);
		ss << "C:\\StarcraftReplayData\\treeT" << treeSize << "M" << ppr.GetRootNode()->GetState() << ".tex";
		myfile.open(ss.str().c_str());
		myfile << "\\usetikzlibrary{positioning}" << endl;
		myfile << "\\usetikzlibrary{shadows}" << endl;
		myfile << "\\tikzstyle{level 1}=[level distance=1.5cm, sibling distance=5.6cm]" << endl;
		myfile << "\\tikzstyle{level 2}=[level distance=1.5cm, sibling distance=2.8cm]" << endl;
		myfile << "\\tikzstyle{level 3}=[level distance=1.5cm, sibling distance=1.4cm]" << endl;
		myfile << "\\tikzstyle{action} = [ellipse, top color=white, bottom color=yellow!20, draw=yellow, node distance=1cm, drop shadow]" << endl;
		myfile << "\\tikzstyle{empty} = [ellipse, top color=white, bottom color=red!20, draw=red, node distance=1cm, drop shadow]" << endl;
		myfile << "\\tikzstyle{obs} = [rectangle, top color=white, bottom color=cyan!20, draw=cyan, node distance=1cm, drop shadow]" << endl;	
		myfile << "\\begin{tikzpicture}[->,>=stealth',grow=down]" << endl;

		myfile << tikz;

		myfile << "\\end{tikzpicture}" << endl;

		myfile.close();
	}

	//test completing branches
	//for(hash_map<string, PPR>::const_iterator it = branches.begin(); it != branches.end(); it++)
	//{
	//	ofstream myfile;
	//	stringstream ss;
	//	PPR ppr = it->second;
	//	ppr.FillInMissingBranches(1.75);
	//	string tikz = ppr.GetRootNode()->ToTikzString("","", 0);
	//	ss << "C:\\StarcraftReplayData\\treeT4M" << ppr.GetRootNode()->GetState() << "FilledIn.tex";
	//	myfile.open(ss.str().c_str());
	//	myfile << "\\usetikzlibrary{positioning}" << endl;
	//	myfile << "\\usetikzlibrary{shadows}" << endl;
	//	myfile << "\\tikzstyle{level 1}=[level distance=1.5cm, sibling distance=11.2cm]" << endl;
	//	myfile << "\\tikzstyle{level 2}=[level distance=1.5cm, sibling distance=5.6cm]" << endl;
	//	myfile << "\\tikzstyle{level 3}=[level distance=1.5cm, sibling distance=2.8cm]" << endl;
	//	myfile << "\\tikzstyle{level 4}=[level distance=1.5cm, sibling distance=1.4cm]" << endl;
	//	myfile << "\\tikzstyle{action} = [ellipse, top color=white, bottom color=yellow!20, draw=yellow, node distance=1cm, drop shadow]" << endl;
	//	myfile << "\\tikzstyle{empty} = [ellipse, top color=white, bottom color=red!20, draw=red, node distance=1cm, drop shadow]" << endl;
	//	myfile << "\\tikzstyle{obs} = [rectangle, top color=white, bottom color=cyan!20, draw=cyan, node distance=1cm, drop shadow]" << endl;	
	//	myfile << "\\begin{tikzpicture}[->,>=stealth',grow=down]" << endl;

	//	myfile << tikz;

	//	myfile << "\\end{tikzpicture}" << endl;

	//	myfile.close();
	//}

	return branches;
}

void testPprToIdid(hash_map<string, PPR> pprs, string inputFile, string outputFile)
{
	InputPprIdid ipi;
	ParseListener *pl = new DefaultParseListener();
	Domain *inputID = new Domain(inputFile, pl);

	Domain domain = ipi.EnterPprModelsIntoIdid(inputID, pprs, "mod", "aj", 2, false);
	inputID->saveAsNet(outputFile);
}


int main(array<System::String ^> ^args)
{
    cout << "Test PPR" << endl;

	//testRepresentations();
	//testInputCSV();
	//testCSVFilter();

	list<string> inputFiles;

	for(int i = 3; i < 6; i ++)
	{
		cout << " T = " << i << endl;
		inputFiles.clear();
		stringstream ss;
		ss << "C:\\StarcraftReplayData\\DIDsimulationsT" << i << "-60.csv";
		inputFiles.push_back(ss.str());
		
		hash_map<string, PPR> pprs = testConvert(i, inputFiles);

		ss.str("");
		ss.clear();
		ss << "..\\HuginApiAddonsTesters\\nets\\TIDID" << i << ".net";

		stringstream ss2;
		ss2 << "..\\HuginApiAddonsTesters\\nets\\TIDID" << i << "_PPR_Models_Inc.net";

		testPprToIdid(pprs, ss.str(), ss2.str());	

		for(hash_map<string, PPR>::const_iterator it = pprs.begin(); it != pprs.end(); it++)
		{
			PPR ppr = it->second;
			ppr.FillInMissingBranches(1.5);

			ofstream myfile;
			stringstream ss;
			string tikz = ppr.GetRootNode()->ToTikzString("","", 0);
			ss << "C:\\StarcraftReplayData\\treeT" << i << "M" << ppr.GetRootNode()->GetState() << "FilledIn.tex";
			myfile.open(ss.str().c_str());
			myfile << "\\usetikzlibrary{positioning}" << endl;
			myfile << "\\usetikzlibrary{shadows}" << endl;
			myfile << "\\tikzstyle{level 1}=[level distance=1.5cm, sibling distance=5.6cm]" << endl;
			myfile << "\\tikzstyle{level 2}=[level distance=1.5cm, sibling distance=2.8cm]" << endl;
			myfile << "\\tikzstyle{level 3}=[level distance=1.5cm, sibling distance=1.4cm]" << endl;
			myfile << "\\tikzstyle{action} = [ellipse, top color=white, bottom color=yellow!20, draw=yellow, node distance=1cm, drop shadow]" << endl;
			myfile << "\\tikzstyle{empty} = [ellipse, top color=white, bottom color=red!20, draw=red, node distance=1cm, drop shadow]" << endl;
			myfile << "\\tikzstyle{obs} = [rectangle, top color=white, bottom color=cyan!20, draw=cyan, node distance=1cm, drop shadow]" << endl;	
			myfile << "\\begin{tikzpicture}[->,>=stealth',grow=down]" << endl;

			myfile << tikz;

			myfile << "\\end{tikzpicture}" << endl;

			myfile.close();
		}

		ss2.str("");
		ss2.clear();

		ss2 << "..\\HuginApiAddonsTesters\\nets\\TIDID" << i << "_PPR_Models_Filled.net";

		testPprToIdid(pprs, ss.str(), ss2.str());
	}


	/*inputFiles.push_back("C:\\StarcraftReplayData\\[iFU.eOnzErG_Zerg][DrainBamaged_Protoss].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[Ross_Terran][Jormungand Brood_Zerg].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[iS-SoraS_Zerg][iuytrewq[F1]_Zerg].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[Nb.Mazur_Protoss][aFF]Surgeon[_Terran].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[3S.Zpad_Protoss][core.i3_Protoss].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[Klub_Terran][Nb.Mazur_Protoss].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[DrainBamaged_Protoss][iFU.eOnzErG_Zerg].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[elena[pain]_Terran][SL]..wishbone-_Protoss].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[dredredre_Terran][Artyk.BishopxD_Protoss].csv");
	inputFiles.push_back("C:\\StarcraftReplayData\\[INH_Terran][unha_Protoss].csv");*/
	
	/*for(int i = 4; i <= 4; i++)
	{
	testConvert(i, inputFiles);
	testFilterConvert(i, inputFiles);
	testPprToIdid(testConvert(i, inputFiles), "..\\HuginApiAddonsTesters\\nets\\TIDID3.net", "..\\HuginApiAddonsTesters\\nets\\TIDID_PPR_Models.net");
	}*/	

	//testMergeTrees();

	cout <<	"DONE" << endl;
	system("pause");
    return 0;
}
